﻿#region Copyright (c) Nicola Gallo All rights reserved.
/*
 * All rights reserved. Reproduction of trasmission of this file, or a portion thereof,
 * is forbidden without prior written permission of Nicola Gallo.
 * 
 * Author: Nicola Gallo
 * Date: 09/04/2011
 * 
 * */
#endregion
namespace PrismMVC.Shell.Data
{
    //.NET References
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Windows.Data;

    /// <summary>
    /// Represents a view data dictionary.
    /// </summary>
    public class ViewDataDictionary : IEnumerable, INotifyPropertyChanged
    {
        //Events

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        //Fields

        private ObservableCollection<ViewDataItem> _viewDataItems;

        //Constructors

        /// <summary>
        /// Creates a new instance of <see cref="ViewDataDictionary"/>.
        /// </summary>
        /// <param name="ViewDataID">ViewDataDictionary identifier.</param>
        internal ViewDataDictionary(string ViewDataID)
        {
            if (string.IsNullOrWhiteSpace(ViewDataID))
            {
                throw new ArgumentException("ViewDataID paramater can not be equals to either null or empty string.");
            }
            this.ViewDataID = ViewDataID;
        }

        //Properties

        /// <summary>
        /// Gets the <see cref="ViewDataDictionary"/> identifier.
        /// </summary>
        public String ViewDataID { get; private set; }

        /// <summary>
        /// Gets <see cref="ViewData"/> items.
        /// </summary>
        protected ObservableCollection<ViewDataItem> ViewDataItems 
        {
            get 
            {
                if (this._viewDataItems == null)
                {
                    this._viewDataItems = new ObservableCollection<ViewDataItem>();
                }
                return this._viewDataItems;
            }
        }

        //Indexers

        /// <summary>
        /// Gets/Sets the value for the input key.
        /// </summary>
        /// <param name="key">ViewDataDictionary item's key.</param>
        /// <returns>ViewDataDictionary item's value.</returns>
        public object this[string key]
        {
            get 
            {
                object retVal = null;
                ViewDataItem viewDataItem = (from item in this.ViewDataItems.AsQueryable()
                                          where item.Key.Equals(key)
                                          select item).FirstOrDefault();
                if (viewDataItem != null)
                {
                    retVal = viewDataItem.Value;
                }
                return retVal;
            }
            set
            {
                ViewDataItem viewDataItem = (from item in this.ViewDataItems.AsQueryable()
                                           where item.Key.Equals(key)
                                           select item).FirstOrDefault();
                if (viewDataItem == null)
                {
                    viewDataItem = new ViewDataItem(key, value);
                    this.ViewDataItems.Add(viewDataItem);
                }
                else
                {
                    viewDataItem.Value = value;
                }
                this.OnPropertyChanged(Binding.IndexerName);
            }
        }

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            return this.ViewDataItems.GetEnumerator();
        }

        /// <summary>
        /// Raises the <see cref="PresentationModel.PropertyChanged"/> event for the input property name.
        /// </summary>
        /// <param name="propertyName"></param>
        protected void OnPropertyChanged(String propertyName)
        {
            if (!string.IsNullOrWhiteSpace(propertyName))
            {
                PropertyChangedEventHandler propertyChangedHnd = this.PropertyChanged as PropertyChangedEventHandler;
                if (propertyChangedHnd != null)
                {
                    propertyChangedHnd(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    }
}